﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using ALiteTeam.PackageTracer.Service.Identifier;

namespace ALiteTeam.PackageTracer.Service
{
    public class EmsIdentifier : Identify
    {
        private Bitmap _Original;
        private Bitmap[] _Pics;
        private int _GrayValue;
        private LevenshteinDistance _Distance;

        public static Dictionary<string, char> Chars = new Dictionary<string, char>()
        {
            // TO 0
            {"0000011100000000111111100000011000110000011000001100001100000110000110000011000011000001100001100000110000110000011000011000001100000110001100000011111110000000011100000",'0'}, 
            // TO 1
            {"0000111000000001101100000000111110000000000011000000000001100000000000110000000000011000000000001100000000000110000000000011000000000001100000000111110110000011111111000",'1'}, 
            // TO 2
            {"0001111100000001111111000000100000110000000000011000000000001100000000001100000000001100000000001100000000001100000000001100000000001100000000000111111110000011111111000", '2'}, 
            // TO 3
            {"0001111100000001111111100000100000110000000000011000000000011000000011111000000001111110000000000011100000000000110000000000011000001000011100000111111100000001111100000", '3'}, 
            // TO 4
            {"0000000110000000000111000000000011100000000011110000000011011000000001101100000001100110000000110011000000111111111000011111111100000000011000000000001100000000000110000", '4'},
            // TO 5
            {"0011111111000001111111100000110000000000011000000000001100000000000111110000000011111110000000000011100000000000110000000000011000001000011100000111111100000001111100000",'5'}, 
            // TO 6
            {"0000111100000000111111000000110000100000011000000000011000000000001101111000000111111110000011100011100001100000110000110000011000001100011100000111111100000000111100000",'6'}, 
            // TO 7
            {"0011111111000001111111100000000000110000000000010000000000011000000000011000000000001000000000001100000000000100000000000110000000000011000000000011000000000001100000000", '7'}, 
            // TO 8
            {"0000111110000000111111100000011000110000001100011000000111001000000001111100000000111110000000110011100000110000011000011000001100001110001110000011111110000000111110000", '8'}, 
            // TO 9
            {"0001111000000001111111000001110001100000110000011000011000001100001110001110000011111111000000111101100000000000110000000000110000001000011000000111111000000001111000000", '9'}, 
        };

        private EmsIdentifier()
        {
            _Distance = new LevenshteinDistance();
        }

        private static EmsIdentifier _Instance;
        public static EmsIdentifier Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new EmsIdentifier();
                }

                return _Instance;
            }
        }

        /// <summary>
        /// 识别单个数字
        /// </summary>
        /// <param name="bmpSingle"></param>
        /// <returns></returns>
        public char GetSingleCode(Bitmap bmpSingle)
        {
            char result = '?';

            //_GrayValue = 113;
            string feature = CodeIdentitierUtil.GetSingleBmpFeature(bmpSingle, _GrayValue);

            decimal currentMaxSimilarity = 0;
            decimal eachTimeValue;

            List<KeyValuePair<int, decimal>> similarities = new List<KeyValuePair<int, decimal>>();

            foreach(string str in Chars.Keys)
            {
                eachTimeValue = _Distance.LevenshteinDistancePercent(feature, str);
                if (eachTimeValue > currentMaxSimilarity)
                {
                    result = Chars[str];
                    currentMaxSimilarity = eachTimeValue;
                }
            }

            if (currentMaxSimilarity < 0.90m)
            {
                result = '_';
            }
            return result;
        }

        /// <summary>
        /// 识别一个验证码图片，返回验证码文字
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public string Identity(Bitmap bitmap)
        {
            string result = string.Empty;
            _Original = new Bitmap(bitmap);

            Bitmap newBitMap;
            newBitMap = CodeIdentitierUtil.GrayByPixels(_Original, false);
            _GrayValue = CodeIdentitierUtil.GetDgGrayValue(_Original);
            newBitMap = CodeIdentitierUtil.GetPicValidByValue(newBitMap, _GrayValue, 6);            
            _Pics = CodeIdentitierUtil.GetSplitPics(newBitMap, 6, 1);

            foreach (var pic in _Pics)
            {
                result += GetSingleCode(pic).ToString();
            }

            return result;
        }

        public string Identity(Stream stream)
        {
            string result;
            
            Bitmap bmp = new Bitmap(stream);            
            result = Identity(bmp);

            return result;
        }
    }
}
